package collection

import (
	"iter"

	"gitee.com/gousing/helper/jsoner"
)

// Stack 使用Slice实现栈（无锁, 不适用于并发场景）
// 栈先进后出，与队列操作顺序相反
// 基于Slice的扩容性能，压栈数据元素建议使用指针
type Stack[T any] struct {
	data []T // 底层切片
	size int // 栈的元素数量
}

func NewStack[T any]() *Stack[T] {
	return new(Stack[T])
}

// Push 压栈
func (s *Stack[T]) Push(val ...T) {
	l := len(val)
	if l > 0 {
		s.size = s.size + l
		s.data = append(s.data, val...)
	}
}

// Pop 出栈消费数据, 返回栈顶的数据, 并移除栈顶的数据
func (s *Stack[T]) Pop() (val T, ok bool) {
	// 栈中元素已空
	if s.size == 0 {
		return
	}
	// 栈顶元素
	val = s.data[s.size-1]
	ok = true
	s.data = s.data[:s.size-1]
	s.size--
	return
}

// Peak 读取方式消费数据, 返回栈顶的数据 不删除栈顶的数据
func (s *Stack[T]) Peak() (val T, ok bool) {
	// 栈中元素已空
	if s.size == 0 {
		return
	}
	// 栈顶元素
	val = s.data[s.size-1]
	ok = true
	return
}
func (s *Stack[T]) Size() int {
	return s.size
}

// IsEmpty 栈是否为空
func (s *Stack[T]) IsEmpty() bool {
	return s.size == 0
}

// Iter 栈数据迭代器(不消费数据)
//   - for v := range stackSync.Iter() {}
func (s *Stack[T]) Iter() iter.Seq[T] {
	return func(yield func(val T) bool) {
		for i := s.size - 1; i >= 0; i-- {
			if !yield(s.data[i]) {
				return
			}
		}
	}
}

// IterAndPop 栈数据迭代消费器(消费数据)
//   - for v := range stackSync.IterAndPop() {}
func (s *Stack[T]) IterAndPop() iter.Seq[T] {
	return func(yield func(val T) bool) {
		for s.size > 0 {
			s.size--
			val := s.data[s.size]
			s.data = s.data[:s.size]
			if !yield(val) {
				return
			}
		}
	}
}

// Values 获取栈数据集切片
func (s *Stack[T]) Values() []T {
	return s.data
}

// Clear 清空栈数据
func (s *Stack[T]) Clear() {
	// 栈中元素已空
	if s.size == 0 {
		return
	}
	s.data = s.data[:0]
	s.size = 0
}

// MarshalJSON 序列化集合接口
func (s *Stack[T]) MarshalJSON() ([]byte, error) {
	return jsoner.Marshal(s.data)
}

// UnmarshalJSON 反序列化集合接口
func (s *Stack[T]) UnmarshalJSON(data []byte) error {
	items := []T{}
	err := jsoner.Unmarshal(data, &items)
	if err != nil {
		return err
	}
	s.data = items
	s.size = len(items)
	return nil
}
